#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2022/5/17 23:19
# @Author  : Grayson Liu
# @Email   : graysonliu@foxmail.com
# @File    : jbb2015.py

import re
from typing import Union
import pandas as pd


def company_rule(x: str) -> str:
    """
    对Company这一列数据的处理操作，用于DataFrame的map方法
    :param x: Company属性的值
    :return: 处理后的值
    """
    # 去掉公司后缀
    x = x.replace("Inc", "")
    x = x.replace("CO., LTD.", "")
    x = x.replace("Co., Ltd.", "")
    x = x.replace(".", "")
    x = x.replace(",", "")
    # 统一命名
    x = x.replace("UNIWIDE", "Uniwide")
    return x


def processor_rule(x: str) -> str:
    """
    对Processor这一列数据的处理操作，用于DataFrame的map方法
    :param x: Processor属性的值
    :return: 处理后的值
    """
    # 处理情况1，使用正则表达式判断CPU的多种情况
    x = re.sub(r"(CPU|2[.]|@|,)(.*G[H|h]z|)", "", x)
    # 处理情况2，直接将（R）代替掉
    x = x.replace("(R)", "")
    return x


def first_cache_rule(x: str) -> str:
    """
    对1st Cache这一列数据的处理操作，用于DataFrame的map方法
    :param x: primary_cache属性的值
    :return: 处理后的primary_cache per core(KB)值
    """
    if x.find("per core") + x.find("Per Core") != -2:
        # 说明：(group1: 1个以上数字)+可能有空格+'KB'+可能有空格+'(I)'或'I'或无+可能有空格+'+'+可能有空格+(group2: 1个以上数字)++可能有空格'KB'+可能有空格+'(D)'或'D'或无
        search_obj = re.match(r"(\d+)\s*KB\s*(?:\(I\)|I|)\s*\+\s*(\d+)\s*KB\s*(?:\(D\)|D|)", x)
        l1i_kb = search_obj.group(1)
        l1d_kb = search_obj.group(2)
        return f"{l1i_kb}KB(I)+{l1d_kb}KB(D)"
    else:
        # 说明：(group1: 1个以上数字)+可能有空格+'KB'
        print(x)
        search_obj = re.match(r"(\d+)\s*KB", x)
        l1_kb = search_obj.group(1)
        return f"{l1_kb}KB(I+D)"


def second_cache_rule(line: pd.Series) -> str:
    """
    对secondary_cache这一列数据的处理操作，用于DataFrame的apply方法（需要用到其他属性的值）
    :param line: DataFrame的一行，类型是pd.Series
    :return: 处理后的secondary_cache per core(KB)值
    """
    x = line["Secondary Cache"]
    cores_per_chip = line["# cores per chip"]
    cores_num = line["# cores"]
    if x.find("per core") + x.find("Per Core") != -2:
        if x.find("M") + x.find("MB") != -2:
            search_obj = re.match(r"(\d+(\.\d+)|\d+)(\s*|)(MB|M)", x)
            l2_kb = int((float(search_obj.group(1)) * 1024))
        else:
            search_obj = re.match(r"(\d+(\.\d+)|\d+)(\s*|)KB", x)
            l2_kb = search_obj.group(1)
        return f"{l2_kb}KB(I+D)"

    elif x.find(";") != -1:
        # x.split("(")[1].split(")")[0]
        xx = x.split("(")[1].split(")")[0]
        x1 = int(xx.split(" ")[0])
        x2 = int(xx.split(" ")[3])
        l1i_kb = x1 // x2
        xx = x.split("(")[2].split(")")[0]
        x1 = int(xx.split(" ")[0])
        x2 = int(xx.split(" ")[3])
        l1d_kb = x1 // x2
        return f"{l1i_kb}KB(I)+{l1d_kb}KB(D)"

    elif x.find("Per Chip") + x.find("per chip") != -2:
        if x.find("M") + x.find("MB") != -2:
            search_obj = re.match(r"(\d+)\s*(MB|M)", x)
            l2_kb = int((int(search_obj.group(1)) * 1024) / cores_per_chip)
        else:
            search_obj = re.match(r"(\d+)\s*KB", x)
            l2_kb = int(int(search_obj.group(1)) / cores_per_chip)

        return f"{l2_kb}KB(I+D)"


def third_cache_rule(line: pd.Series) -> str:
    """
    对Other Cache这一列数据的处理操作，用于DataFrame的map方法
    :param line: 1st Cache属性的值由于数据可能是缺失值（即NaN，float型）也可能是字符串
    :return: 处理后的3rd Cache per chip(MB)值
    """
    x = line["Tertiary Cache"]
    cores_per_chip = line["# cores per chip"]
    cores_num = line["# cores"]
    if x.find("per chip") + x.find("Per Chip") + x.find("per chipS") != -3:
        if x.find("M") + x.find("MB") != -2:
            search_obj = re.match(r"(\d+(\.\d+)|\d+)(\s*|)(MB|M)", x)
            l2_kb = float(search_obj.group(1))
        else:
            search_obj = re.match(r"(\d+(\.\d+)|\d+)(\s*|)KB", x)
            l2_kb = int(search_obj.group(1)) / 1024
        return f"{l2_kb}MB"
    elif x.find("L3") + x.find("per 4-core") != -2:
        search_obj = re.match(r"(\d+)\s*MB", x)
        l3_mb = int(search_obj.group(1)) * (cores_per_chip / 4)
        return f"{l3_mb}MB"
    elif +x.find("on chip per core") != -1:
        search_obj = re.match(r"(\d+)\s*MB", x)
        l3_mb = int(search_obj.group(1)) * cores_per_chip
        return f"{l3_mb}MB"
    else:
        return "0"


def memory_rule(x: str) -> str:
    """
    对Memory这一列数据的处理操作，用于DataFrame的map方法
    :param x: Memory属性的值
    :return: 处理后的Memory(GB)值
    """
    if x.find("GB") != -1:
        search_obj = re.match(r"(\d+)(\s*|)GB", x)
        return f"{search_obj.group(1)}GB"
    else:
        return f"{int(x)}GB"


def report_link_rule(x: str) -> str:
    """
    对Report Link这一列数据的处理操作，用于DataFrame的map方法
    :param x: Report Link属性的值
    :return: 处理后的Report Link值
    """
    search_obj = re.match(r'(http:.+html)"<A', x)
    return search_obj.group(1)
